package com.grj.park.boot.controller;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.grj.park.boot.domain.R;
import com.grj.park.boot.domain.Role;
import com.grj.park.boot.domain.RolePermission;
import com.grj.park.boot.domain.RolePermissionBody;
import com.grj.park.boot.domain.*;
import com.grj.park.boot.service.RolePermissionService;
import com.grj.park.boot.service.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/role")
@Api(tags = "角色管理")
@RequiredArgsConstructor
public class RoleController {

    private final RoleService roleService;
    private final RolePermissionService rolePermissionService;

    /**
     * 分页查询角色列表
     * @param currentPage 当前页码
     * @param pageSize 每页大小
     * @param role 查询条件
     * @return 分页结果
     */
    @GetMapping("/page")
    @ApiOperation("分页查询角色列表")
    @PreAuthorize("hasAuthority('role:page')")
    public R<Page<Role>> fetchRolePage(
            @RequestParam int currentPage,
            @RequestParam int pageSize,
            @RequestParam String role,
            @RequestParam(required = false) List<Date> during
    ) {
        return R.ok(roleService.fetchRolePage(currentPage, pageSize, JSONUtil.toBean(role, Role.class), during));
    }

    /**
     * 添加角色
     * @param rolePermissionBody 角色对象
     * @return 添加结果
     */
    @PostMapping
    @ApiOperation("添加角色")
    @PreAuthorize("hasAuthority('role:post')")
    public R<Void> postRole(@RequestBody @Valid RolePermissionBody rolePermissionBody) {
        Role role = rolePermissionBody.getRole();
        roleService.postRole(role);
        List<RolePermission> rolePermissions = rolePermissionBody.getPermissionIds().stream().map(permissionId -> {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setPermissionId(permissionId);
            rolePermission.setRoleId(rolePermissionBody.getRole().getRoleId());
            return rolePermission;
        }).collect(Collectors.toList());
        rolePermissionService.saveBatch(rolePermissions);
        return R.okMsg("添加角色成功");
    }

    /**
     * 更新角色
     * @param role 角色对象
     * @return 更新结果
     */
    @PutMapping
    @ApiOperation("更新角色")
    @PreAuthorize("hasAuthority('role:put')")
    public R<Void> putRole(@RequestBody @Valid Role role) {
        roleService.putRole(role);
        return R.okMsg("更新角色成功");
    }

    /**
     * 删除角色
     * @param roleId 角色 ID
     * @return 删除结果
     */
    @DeleteMapping("/{roleId}")
    @ApiOperation("删除角色")
    @PreAuthorize("hasAuthority('role:delete')")
    public R<Void> delRole(@PathVariable Long roleId) {
        roleService.delRole(roleId);
        return R.okMsg("删除角色成功");
    }

    /**
     * 批量删除角色
     * @param roleIds 角色 ID 数组
     * @return 删除结果
     */
    @DeleteMapping("/batch/delete")
    @ApiOperation("批量删除角色")
    @PreAuthorize("hasAuthority('role:batch:delete')")
    public R<Void> batchDelRole(@RequestParam List<Long> roleIds) {
        roleService.batchDelRole(roleIds);
        return R.okMsg("批量删除角色成功");
    }

    /**
     * 获取角色详情
     * @param id 角色 ID
     * @return 角色详情
     */
    @GetMapping("/{id}")
    @ApiOperation("获取角色详情")
    @PreAuthorize("hasAuthority('role:get')")
    public R<Role> fetchRoleById(@PathVariable Long id) {
        return R.ok(roleService.fetchRoleById(id));
    }

    @GetMapping("/permission/{roleId}")
    @ApiOperation("获取角色权限列表")
    @PreAuthorize("hasAuthority('role:permission:list')")
    public R<List<RolePermission>> fetchRolePermissionList(@PathVariable Long roleId) {
        return R.ok(rolePermissionService.list(Wrappers.lambdaQuery(RolePermission.class).eq(RolePermission::getRoleId, roleId)));
    }

    @PutMapping("/permission/{roleId}")
    @ApiOperation("更新角色权限")
    @PreAuthorize("hasAuthority('role:permission:put')")
    public R<Void> putRolePermission( @PathVariable Long roleId, @RequestBody List<Long> permissionIds) {
        System.out.println(roleId);
        System.out.println(permissionIds);
        rolePermissionService.remove(Wrappers.lambdaQuery(RolePermission.class).eq(RolePermission::getRoleId, roleId));
        List<RolePermission> rolePermissions = rolePermissionService.listAll(roleId);
        List<Long> rolePermissionIds = rolePermissions.stream().map(RolePermission::getPermissionId).collect(Collectors.toList());
        List<Long> savePermissionIds = permissionIds.stream().filter(permissionId -> !rolePermissionIds.contains(permissionId)).collect(Collectors.toList());
        List<Long> updatePermissionIds = permissionIds.stream().filter(permissionId -> rolePermissionIds.contains(permissionId)).collect(Collectors.toList());

        if(!savePermissionIds.isEmpty()){
            List<RolePermission> saveRolePermissions = savePermissionIds.stream().map(permissionId -> {
                RolePermission rolePermission = new RolePermission();
                rolePermission.setPermissionId(permissionId);
                rolePermission.setRoleId(roleId);
                return rolePermission;
            }).collect(Collectors.toList());
            rolePermissionService.saveBatch(saveRolePermissions);
        }
        if(!updatePermissionIds.isEmpty()){
            List<RolePermission> updateRolePermissions = updatePermissionIds.stream().map(permissionId -> {
                RolePermission rolePermission = new RolePermission();
                rolePermission.setPermissionId(permissionId);
                rolePermission.setRoleId(roleId);
                return rolePermission;
            }).collect(Collectors.toList());
            rolePermissionService.updateRolePermission(updateRolePermissions);
        }
        return R.okMsg("更新角色权限成功");
    }
}
